package com.dtguai.admin.web.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.dtguai.admin.util.redis.RedisUtil;
import com.dtguai.admin.web.sys.model.SysAdminToken;
import com.dtguai.admin.web.sys.oauth2.TokenGenerator;
import com.dtguai.admin.web.sys.service.SysUserTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * sysUserTokenService
 *
 * @author guo
 * @date 2019年1月23日11:22:19
 */
@Service("sysUserTokenService")
public class SysUserTokenServiceImpl implements SysUserTokenService {

    @Autowired
    RedisUtil redisUtil;

    private static final String WEB_TOKEN_ADMIN_ID = "web:token:adminId:";

    private static final String WEB_TOKEN = "web:token:";

    /**
     * 过期时间 12 小时
     */
    private static final int EXPIRE = 60 * 60 * 12 * 1000;

    /**
     * 过期后 2小时内再次活跃刷新token时间
     */
    public static final int REFRESH_EXPIRE = 60 * 60 * 2 * 1000;

    @Override
    public SysAdminToken createToken(Integer adminId) {
        //从redis删除之前废弃的token
        Optional.ofNullable(getToken(adminId))
                .map(SysAdminToken::getToken)
                .ifPresent(x -> redisUtil.delete(getTokenKey(x)));

        //生成token
        SysAdminToken tokenEntity = new SysAdminToken()
                .setAdminId(adminId)
                //生成token
                .setToken(TokenGenerator.generateValue())
                .setUpdateTime(new Date())
                //过期时间
                .setExpireTime(getExpireTime())
                //token有效时间毫秒
                .setExpire(EXPIRE);

        //插入缓存
        addRedisTokenEntity(tokenEntity);

        return tokenEntity;
    }

    @Override
    public void refreshTokenTime(String token) {
        //从redis获取token实体
        SysAdminToken tokenEntity = this.getToken(token);
        tokenEntity.setExpireTime(getExpireTime());
        //插入缓存
        addRedisTokenEntity(tokenEntity);
    }

    @Override
    public void logout(Integer adminId) {
        //获取token对象
        SysAdminToken token = getToken(adminId);
        //删除token
        redisUtil.delete(getTokenKey(adminId));
        if (null != token) {
            //删除token对象
            redisUtil.delete(getTokenKey(token.getToken()));
        }
        //删除权限
        String key = ShiroServiceImpl.WEB_SHIRO_PERMISSIONS + adminId;
        redisUtil.delete(key);
        key = ShiroServiceImpl.WEB_SHIRO_ADMIN_INFO + adminId;
        redisUtil.delete(key);
    }

    @Override
    public SysAdminToken getToken(Integer adminId) {
        return redisUtil.getModel(getTokenKey(adminId), SysAdminToken.class);
    }

    @Override
    public SysAdminToken getToken(String token) {
        return redisUtil.getModel(getTokenKey(token), SysAdminToken.class);
    }

    private String getTokenKey(Integer id) {
        return WEB_TOKEN_ADMIN_ID + id;
    }

    private String getTokenKey(String token) {
        return WEB_TOKEN + token;
    }

    private Date getExpireTime() {

        //当前时间+EXPIRE =过期时间
        return new Date((new Date()).getTime() + EXPIRE);
    }

    private void addRedisTokenEntity(SysAdminToken tokenEntity) {
        //插入缓存
        redisUtil.setString(getTokenKey(tokenEntity.getAdminId()), JSON.toJSONString(tokenEntity), EXPIRE, TimeUnit.MILLISECONDS);
        redisUtil.setString(getTokenKey(tokenEntity.getToken()), JSON.toJSONString(tokenEntity), EXPIRE, TimeUnit.MILLISECONDS);
    }
}
